#!/usr/bin/env python
#coding=utf-8


import datetime
import pandas as pd
from app.bill.models.bill_event import BillEvent
from app.celery_task.models.celery_task import CeleryTask
# from common.sa_platform import SaPlatform

from sqlalchemy.orm import Session
from core.response import resp_500
from core.logger import logger
from common.utils import is_empty


class BillEventHandler(object):
    def __init__(self):
        pass


    def get_event_search(self, db: Session, page: int, per_page: int, field: str, value: str):
        """
        资产事件记录表, 根据表字段-模糊查询, 获取事件数据
        """
        try:
            field_info = {field: value}
            order_info = {"bill_cycle": "desc", "cloud_platform": "asc"}
            result = BillEvent.filter_by_field_search(db, page, per_page, field_info, order_info)
            if not result:
                logger.warning(f"get bill event search, result is null => {field}:{value}")
                return False, None

        except Exception as e:
            message = f"get bill event search by {field}:{value} error"
            logger.exception(f"{message} => {e}")
            return resp_500(message)

        return True, result



    def get_event_match(self, db: Session, page: int, per_page: int, field: str, value: str):
        """
        资产事件记录表, 根据表字段-完全查询, 获取资产事件
        """
        try:
            result = BillEvent.filter_by_field_match(db, page, per_page, {field: value})
            if not result:
                logger.warning(f"get bill event match failed, result is null => {field}:{value}")
                return True, []

        except Exception as e:
            message = f"get bill event match by {field}:{value} error"
            logger.exception(f"{message} => {e}")
            return resp_500(message)

        return True, result


    def get_event_item(self, db: Session, bill_cycle: str, cloud_platform: str, info_type: str, info_item: str):
        """
        资产事件记录表, 根据信息条目查询, 获取资产事件
        """
        try:
            result = BillEvent.get_object_info_by_item(db, bill_cycle, cloud_platform, info_type, info_item)
            if not result:
                logger.warning(f"get bill event item failed, result is null")
                return True, []
            
        except Exception as e:
            message = f"get bill event item error"
            logger.exception(f"{message} => {e}")
            return resp_500(message)

        return True, result


    def add_event(self, db: Session, data: dict):
        """
        增加资产事件记录信息
        """
        try:
            # 添加到数据库
            result = BillEvent.add(db, data)
            if not result:
                logger.error(f"add bill event to database failed")
                return False
        except Exception as e:
            message = f"add bill event error"
            logger.exception(f"{message} data:{data} => {e}")
            return resp_500(message)

        return True



    def update_event(self, db: Session, data: dict):
        """
        修改资产事件记录信息
        """
        try:
            bill_event_object = BillEvent.get_object_by_uuid(db, data["uuid"])
            if not bill_event_object:
                # 如果不存在， 则异常返回
                logger.error(f"update bill event failed, uuid:{data['uuid']} not exist")
                return False

            # 更新数据库
            result = BillEvent.update(db, data)
            if not result:
                logger.error(f"update bill event to database failed")
                return False
        except Exception as e:
            message = f"update bill event error "
            logger.exception(f"{message} data:{data} => {e}")
            return resp_500(message)

        return True



    def delete_event(self, db: Session, data: dict):
        """
        删除资产事件记录信息
        """
        try:
            bill_event_object = BillEvent.get_object_by_uuid(db, data['uuid'])
            if not bill_event_object:
                # 如果不存在， 则异常返回
                logger.error(f"delete bill event failed, uuid:{data['uuid']} not exist")
                return False

            # 删除
            BillEvent.delete_object_by_uuid(db, data['uuid'])
        except Exception as e:
            message = f"delete bill event error"
            logger.exception(f"{message} data:{data} => {e}")
            return resp_500(message)

        return True



    def post_bill_event_workorder_task(self, db: Session, data: dict):
        """
        启动同步工单信息的异步任务
        """
        try:
            # 启动异步任务
            from app.bill.task import bill_event_from_work_order_async
            # 判断任务是否已经启动，控制只有一个任务在跑。 如果任务可以多个同时进行，则无需这一步判断。
            task_name = bill_event_from_work_order_async.name.split(".")[-1]
            if CeleryTask.is_progress_on_name(db, task_name):
                logger.error(f"task: {task_name} was stared")
                return False

            task = bill_event_from_work_order_async.delay(data["bill_cycle"])
            task_data = {
                "name": task_name,
                "tid": task.id,
                "state": task.state
            }
        except Exception as e:
            message = f"start bill event workorder task error, bill_cycle:{data['bill_cycle']}"
            logger.exception(f"{message} => {e}")
            return resp_500(message)

        logger.info(f"add task: {task_name} success")
        return task_data




    def task_update_from_work_order_handle(self, db: Session, bill_cycle: str):
        """
        更新工单事件信息的处理函数
        """
        try:
            if not bill_cycle:
                # 如果没指定，则为上月
                last_month = datetime.date(datetime.date.today().year, datetime.date.today().month, 1) - datetime.timedelta(days=1)
                bill_cycle = last_month.strftime("%Y-%m")
            else:
                year_month = datetime.date(int(bill_cycle.split("-")[0]), int(bill_cycle.split("-")[1]), 1)
                bill_cycle = year_month.strftime("%Y-%m")

            # sa_platform = SaPlatform()
            # work_order_infos = sa_platform.get_work_order_infos(bill_cycle)
            work_order_infos = []
            
            for work_order_info in work_order_infos:
                bill_event_object = BillEvent.get_object_by_relation_id(db, bill_cycle, work_order_info["relation_id"])
                # 如果已经存在，则不更新
                if bill_event_object:
                    logger.warning(f"work order id:{work_order_info['relation_id']} was exists, do noting")
                    continue
                
                # 如果不存在，则添加
                result = BillEvent.add(db, work_order_info)
                if not result:
                    logger.error(f"task handle add bill event to database failed")
                    return False
                
        except Exception as e:
            logger.error(f"update bill event from work order error=>{e}")
            return False

        logger.info(f"update bill event from work order success")
        return True




